package jfc.core;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.*;

import jfc.ui.GamePanel;

/**
 *  @author Yann Le Gall
 *  ylegall@gmail.com
 *  Oct 25, 2009 4:38:20 PM
 */
public class Cascade extends CardHolder {

    private List<Card> cards;

    public Cascade(Point p) {
        super(p);
        cards = new ArrayList<Card>(25);
    }

    public boolean canAdd(Card c) {
    	if(c == null) return false;
        if (cards.size() < 1) {
            return true;
        } else {
            Card top = cards.get(cards.size() - 1);
            if (!top.isSameColor(c) && top.compareTo(c) == 1) {
                return true;
            }
            return false;
        }
    }

    public final void add(List<Card> list) {
        while(!list.isEmpty()) {
            add(list.remove(0));
        }
    }
    
    public Card peekTop() {
    	return cards.get(cards.size()-1);
    }

    public void add(Card c) {
        c.setLocation(x, y + GamePanel.CARDGAP*(cards.size()));
        cards.add(c);
    }

    public List<Card> remove(int num) {
        if(cards.isEmpty() || num < 1) return null;
        else {
        	LinkedList<Card> list = new LinkedList<Card>();
        	int size = cards.size();
        	while(size > 0 && num > 0) {
        		list.addFirst(cards.remove(size-1));
        		num--; size--;
        	}
        	return list;
        }
    }

    @Override
    public Point getDestination() {
        if(cards.isEmpty()) {
            return getLocation();
        }
        else {
            Point p = cards.get(cards.size()-1).getLocation();
            p.y += GamePanel.CARDGAP;
            return p;
        }
    }
    
    public int getTopValue() {
    	return (cards.isEmpty())? 0 : cards.get(cards.size()-1).getValue();
    }

    public int numCards() { return cards.size(); }
    public void clear() { cards.clear(); }

    public boolean containsPoint(Point p) {
        Rectangle r = new Rectangle(this);
        r.height += (cards.size() - 1)*GamePanel.CARDGAP;
        return r.contains(p);
    }

    public boolean isValidStack(int start) {
        Card c = cards.get(start);
        for(; start < cards.size() - 1; start++) {
            Card next = cards.get(start + 1);
            if(c.compareTo(next) != 1 || c.isSameColor(next))
                return false;
            c = next;
        }
        return true;
    }

    public boolean topCardContains(Point p) {
    	if(cards.isEmpty()) {
    		return this.contains(p);
    	} else {
    		return cards.get(cards.size() - 1).contains(p);
    	}
    }

    public int indexOf(Point p) {
        int size = (cards.isEmpty())? 0 : cards.size() - 1;
        int index = (p.y - y)/GamePanel.CARDGAP;
        return (index > size)? size: index;
    }

    public List<Card> getCards(Point p) {
        int index = indexOf(p);
        if(!isValidStack(index))
            return null;
        LinkedList<Card> tempList = new LinkedList<Card>();
        int size = cards.size();
        while( size > index) {
        	tempList.addFirst(cards.remove(size -1));
        	size--;
        }
        return tempList;
    }

    public void draw(Graphics2D g2) {
        if (!cards.isEmpty()) {
            for (Card c : cards) {
                c.draw(g2);
            }
        } else {
            Color c = g2.getColor();
            g2.setColor(Color.black);
            g2.drawRoundRect(x, y, width, height, 10, 10);
            g2.setColor(c);
        }
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        for(Card c : cards) {
            sb.append(c.toString());
            sb.append(",");
        }
        return sb.toString();
    }
}
